import { PUBSUB_REQUEST } from '@/constants/pubsub'
import axios from 'axios'
import PubSub from 'pubsub-js'

import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import type { RequestClientOptions, RequestConfig } from '@/types/request'
//操作正常code，支持String、Array、int多种类型
const successCode = [200, 1]
//登录失效code
const invalidCode = 480
//无权限code
const noPermissionCode = 409
// 请求超时时间(毫秒)
const timeout = 8000
// 基础url地址
const baseURL = import.meta.env.VITE_APP_API_PREFIX

/**
 *
 * @description 处理code异常
 * @param {*} code
 * @param {*} msg
 */
// 处理错误码
// 这里的错误处理不做直接处理，通过发布订阅模式处理，解耦对其他模块的依赖，只在需要的地方订阅处理即可
const handleCode = (code: number, msg: string) => {
  switch (code) {
    case invalidCode:
      PubSub.publish(PUBSUB_REQUEST.invalidCode, msg)
      break
    case noPermissionCode:
      PubSub.publish(PUBSUB_REQUEST.noPermissionCode, msg)
      break
    default:
      PubSub.publish(PUBSUB_REQUEST.message, `后端接口${code}异常`)
      break
  }
}

// 创建axios实例
const instance = axios.create({
  // `baseURL` 将自动加在 `url` 前面，除非 `url` 是一个绝对 URL。
  baseURL,
  // 指定请求超时的毫秒数
  timeout,
  // 自定义请求头
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',
    'client-type': 'tenant',
    'terminal-type': 'web',
  },
})

// 请求前拦截
instance.interceptors.request.use(
  (config: any) => {
    const userStore = useUserStore()
    const { token } = storeToRefs(userStore)
    // 存在token
    if (token) {
      config.headers = {
        ...config.headers,
        ['accessToken']: token.value,
      }
    }

    return config
  },
  (error) => {
    return Promise.reject(error)
  },
)
// 响应拦截
instance.interceptors.response.use(
  async (response) => {
    const res = response.data
    const { data } = response

    if (
      response.config.url === 'community-order-api/pms/static-resource/download/bin' ||
      response.headers['content-type'] === 'application/octet-stream'
    ) {
      return Promise.resolve(data)
    }
    const resultCode = data?.resultCode || data?.result?.resultCode
    // 请求成功
    if (successCode.indexOf(resultCode) !== -1) {
      return Promise.resolve(res?.result)
    } else {
      // 请求失败
      handleCode(resultCode, data.message)
      return Promise.reject()
    }
  },
  (error) => {
    // 如果返回有data，校验失败code
    if (error.response && error.response.data) {
      const { status, data } = error.response
      handleCode(status, data?.message || error?.message)
    }
    return Promise.reject(error)
  },
)

export default instance
